<!-- 封装第三方组件 Easymde -->

<template>
  <div class="vue-easymde-editor">
    <textarea ref="textArea"></textarea>
  </div>
</template>
<script setup lang="ts">
// EasyMDE 用于实例化   Options 配置的类型
import EasyMDE, { Options } from 'easymde';
import { onMounted, onUnmounted, ref, watch } from 'vue';
interface Props {
  modelValue?: string
  options?: Options
}
// 组件事件
interface Events {
  // 更新 modeValue 事件
  (type: 'update:modelValue', value: string): void
  // 表单事件
  (type: 'change', value: string): void
  // 表单事件
  (type: 'blur'): void
}
const props = defineProps<Props>()
const emits = defineEmits<Events>()
// 获取 textArea
const textArea = ref<null | HTMLTextAreaElement>()
// 创建变量为 null 类型  或者EasyMDE
let easyMDEInstance: EasyMDE | null = null
// 获取父组件传入的modelValue
const innerValue = ref(props.modelValue || '')
// 因为 props.modelValue 为异步 所以要监听
watch(() => props.modelValue, (newValue) => {
  // 如果这个实例存在
  if (easyMDEInstance) {
    // 并且innerValue 不等于 newValue
    if (innerValue.value !== newValue) {
      // 把他赋值为新传递的值， 或者就是空
      easyMDEInstance.value(newValue || '')
    }
  }
})
onMounted(() => {
  // 如果节点存在
  if (textArea.value) {
    const config: Options = {
      // 如果没传就默认为空对象
      ...(props.options || {}),
      element: textArea.value,
      initialValue: innerValue.value
    }
    // 创建实例
    easyMDEInstance = new EasyMDE(config)
    // 监听对应事件
    easyMDEInstance.codemirror.on('change', () => {
      if (easyMDEInstance) {
        // 拿到当前值输入框的值 easyMDEInstance.value() 
        const updateValue = easyMDEInstance.value()
        // 更新 innerValue的值
        innerValue.value = updateValue
        // 发送自定义事件
        emits('update:modelValue', innerValue.value)
        emits('change', updateValue)
      }
    })
    // 监听对应事件
    easyMDEInstance.codemirror.on('blur', () => {
      if (easyMDEInstance) {
        emits('blur')
      }
    })
  }
})
// 销毁实例
onUnmounted(() => {
  if (easyMDEInstance) {
    easyMDEInstance.cleanup()
  } else {
    return null
  }
})
const clearInnerValue = () => {
  if (easyMDEInstance) {
    easyMDEInstance.value('')
  }
}
const getEasyMDEInstance = () => {
  if (easyMDEInstance) {
    return easyMDEInstance
  }
}
//  setup 语法糖 对应组件实例 不是公开的要暴露出去
defineExpose({
  clearInnerValue,
  getEasyMDEInstance
})
</script>
<style>
.is-invalid.vue-easymde-editor {
  border: 1px solid red;
}
</style>